package com.winbomb.kingcard.base;

import com.winbomb.kingcard.Action;
import com.winbomb.kingcard.IBattle;
import com.winbomb.kingcard.ICard;
import com.winbomb.kingcard.IGameLogic;
import com.winbomb.kingcard.IPlayer;
import com.winbomb.kingcard.IState;
import com.winbomb.kingcard.Pos;
import com.winbomb.kingcard.base.anim.IPlayable;
import com.winbomb.kingcard.base.anim.impl.ActionAnim;
import com.winbomb.kingcard.base.anim.impl.AttackAnim;
import com.winbomb.kingcard.base.anim.impl.BattleResultAnim;
import com.winbomb.kingcard.utils.GameUtils;

public enum BattleState implements IState {

	BATTLE_START {
		public boolean isWaitInput() {
			return false;
		}

		public void nextState(IGameLogic game) {
			IBattle battle = game.getBattle();
			if (!battle.getInvader().isHuman() && !battle.getGuarder().isHuman()) {
				game.setState(INVADER_SET_GENERAL);
				return;
			}

			addAnimation(game, AnimManager.ANIM_BATTLE_START);
		}
	},
	/**
	 * 侵略方叫阵(选择一张将牌与对方比大小,如果这张将牌胜出,那么所有与该将牌
	 * 
	 * 同色的兵牌都将获得技能鼓舞.
	 * 
	 */
	INVADER_SET_GENERAL {
		public void nextState(IGameLogic game) {
			game.getBattle().changeTurn();
			game.setState(GUARDER_SET_GENERAL);
		}
	},

	/**
	 *防御方叫阵
	 */
	GUARDER_SET_GENERAL {
		public void nextState(IGameLogic game) {
			game.getBattle().prepare();
			game.setState(OFFENSIVE_ARRAY);
		}
	},
	OFFENSIVE_ARRAY {
		// 先手列阵
		public void nextState(IGameLogic game) {
			game.getBattle().changeTurn();
			game.setCurrPlayer(game.getBattle().getCurrTurner());
			game.setState(DEFENSIVE_ARRAY);
		}
	},
	DEFENSIVE_ARRAY {
		// 后手列阵
		public void nextState(IGameLogic game) {
			game.getBattle().changeTurn();
			game.setCurrPlayer(game.getBattle().getCurrTurner());
			game.setState(SELECT_ATK_CARD);
		}
	},
	SELECT_ATK_CARD {
		public void nextState(IGameLogic game) {
			IBattle battle = game.getBattle();
			ICard[] atkCards = battle.getAtkCards();

			for (int i = 0; i < atkCards.length; i++) {
				if (atkCards[i] != null && atkCards[i].isSelected()) {
					battle.setCurrAtkCard(i);
					atkCards[i].setSelected(false);
					break;
				}
			}

			game.setState(FIGHT_START);
		}
	},
	FIGHT_START {
		public boolean isWaitInput() {
			return false;
		}

		public void nextState(IGameLogic game) {
			IBattle battle = game.getBattle();

			// 如果已经没有可供进攻的对象了
			ICard[] atkableCards = battle.getAtkableTargets();
			if (atkableCards.length == 0) {
				// 如果进攻卡片里面还有暗牌,则可以继续选择进攻的牌
				ICard[] atkCards = battle.getAtkCards();
				for (ICard card : atkCards) {
					if (card != null && card.testFlag(Card.IS_UNOPEN_CARD)) {
						game.setState(SELECT_ATK_CARD);
						return;
					}
				}

				battle.judge();
				if (battle.getInvader().isHuman() || battle.getGuarder().isHuman()) {
					game.setCurrPlayer(game.getPlayers()[0]);
					addAnimation(game, AnimManager.ANIM_WIN_LOSE);
				}
				game.setState(BATTLE_END);
				return;
			}

			game.setState(SELECT_ATK_TARGET);
		}
	},
	SELECT_ATK_TARGET {
		public void nextState(IGameLogic game) {

			// 设置被进攻的卡片
			IBattle battle = game.getBattle();
			ICard[] defCards = battle.getDefCards();
			for (int i = 0; i < defCards.length; i++) {
				if (defCards[i] != null && defCards[i].isSelected()) {
					battle.setCurrAtkTarget(i);
					defCards[i].setSelected(false);
					break;
				}
			}

			// 战斗开始. 如果战斗双方都是电脑,则不显示战斗的详细过程
			if (!battle.getInvader().isHuman() && !battle.getGuarder().isHuman()) {
				game.setState(BattleState.FIGHT_START);
				battle.fight();
				return;
			}

			AnimManager animManager = getAnimManager(game);
			int atkIdx = battle.getCurrAtkCardIdx();
			int defIdx = battle.getCurrAtkTargetIdx();
			int atkY = 95, defY = 225;
			if (battle.getCurrTurner() == battle.getTarget()) {
				atkY = 225;
				defY = 95;
			}

			// 如果进攻者是human,由于human总在下面,所以要交换坐标
			if (game.getCurrTurn().isHuman() && battle.getInvoker().isHuman()) {
				atkY += defY;
				defY = atkY - defY;
				atkY = atkY - defY;
			}

			Pos srcPos = new Pos(112 + 64 * atkIdx, atkY);
			Pos destPos = new Pos(112 + 64 * defIdx, defY);
			AttackAnim fightAnim = AnimManager.ATTACK_ANIM;
			fightAnim.reset();
			fightAnim.set(srcPos, destPos);
			animManager.addAnimation(fightAnim);
		}
	},
	CHASE_AND_ATTACK {
		public void nextState(IGameLogic game) {
			IBattle battle = game.getBattle();
			IPlayer winner = battle.getWinner();

			if (winner.getAction() == Action.CHASE_ATTACK) {
				game.setState(SELECT_CHASE_CARDS);

			} else {
				battle.getWinner().withdraw();
				game.setState(GameState.ROUND_END);
			}

			// 显示追击的提示
			ActionAnim anim = AnimManager.ACTION_ANIM;
			anim.reset();
			anim.setTargetPlayer(battle.getWinner());
			anim.setAction(winner.getAction());
			addAnimation(game, anim);

		}
	},
	SELECT_CHASE_CARDS {
		public void nextState(IGameLogic game) {
			game.getBattle().chaseAttack();
			game.setCurrPlayer(game.getBattle().getLoser());
			game.setState(GameState.SELECT_DEF_CARDS);
		}
	},
	BATTLE_END {
		public void nextState(IGameLogic game) {

			IBattle battle = game.getBattle();

			// 清除winner和loser的battleCards中defeated掉得牌
			GameUtils.removeDefeatCards(battle.getWinner().getBattleCards());
			GameUtils.removeDefeatCards(battle.getLoser().getBattleCards());

			battle.pickCaptives();
			battle.finish();
			battle.getLoser().withdraw();

			// 播放胜利和失败的动画
			BattleResultAnim anim = AnimManager.BATTLE_RESULT_ANIM;
			anim.reset();
			int winnerLoss = (battle.isInvaderWin()) ? battle.getInvadeLoss() : battle.getGuardLoss();
			int loserLoss = (battle.isInvaderWin()) ? battle.getGuardLoss() : battle.getInvadeLoss();
			anim.setWinner(battle.getWinner(), winnerLoss);
			anim.setLoser(battle.getLoser(), loserLoss);
			addAnimation(game, anim);

			// 如果没有全歼敌军,或者失败方已经灭亡,则战斗到此结束
			if (!battle.getLoser().isAlive()) {
				battle.getWinner().withdraw();
				game.setState(GameState.ROUND_END);
				return;

			}

			game.setCurrPlayer(battle.getWinner());
			game.setState(CHASE_AND_ATTACK);

			if (game.getCurrPlayer().isHuman()) {
				game.setPause(false);
			}
		}
	};

	public static final String TAG = "BattleState";

	public boolean isWaitInput() {
		return true;
	}

	public static AnimManager getAnimManager(IGameLogic game) {
		return ((GameLogic) game).getAnimManager();
	}

	public static void addAnimation(IGameLogic game, int animId) {
		AnimManager animManager = getAnimManager(game);
		animManager.addAnimation(animId);
	}

	public static void addAnimation(IGameLogic game, IPlayable anim) {
		AnimManager animManager = getAnimManager(game);
		animManager.addAnimation(anim);
	}
}
